home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™94
/
Talks & Papers
/
Timothy Knox
/
yerk 3.66
/
System source
/
Mod
< prev
next >
Wrap
Text File
|
1994-06-24
|
7KB
|
171 lines
\ Module - support for separately compiled modules in Yerk
\ 12/04/84 CBD Version 1
\ 10/22/85 cdn Echo during module load
\ 12/20/85 cdn Reuse target BIN file- so as not to wrestle file from folder
\ 7/11/86 cdn Modify flagging technique in BldBits for faster run time
\ 7/26/86 cdn Added ^last word defined in module as first 4 bytes
\ 8/31/88 rfl ***WARNING***
\ The code to become a module must clear all data areas it uses.
\ If it doesn't, the second pass will have differing bytes
\ than the first pass and bldbits will think they are
\ relocatable addresses!
\ 5/06/93 rfl added 'immediates' to handle marking immediate imports
\ 6/04/93 rfl sfind now doesn't map to uppercase, as advertised in glossary
\ screate modified for source documentation...screate and sfine
\ moved to 'file' ... 'module' saves doc state and sets to -doc
\ 1/01/94 rfl change set-file to setNamePtr: topfile
\ 1/05/94 rfl dispose of old module for module compile changed to keep
\ old install bit.
Decimal
\ use: You must define the imports for a module in the resident
\ portion of your application with the statement:
\ FROM moduleName IMPORT{ imp0 ... impN }
\ This will create a module definition for filename "moduleName"
\ and import definitions for all imported names.
\ Later, you must build the module with the statement
\ module "moduleName"
\ This will look up the mod def for moduleName, and generate a
\ relocatable module from its source file.
\ After the module is built, any reference to one of the imported names
\ will cause the module to be loaded. Imported names are local to
\ the vocabulary that they are defined in.
\ Define names to be imported from module - FROM modName IMPORT{ ... }
\ ( -- modDefCfa )
: From modDef latest Name> ;
\ imp def data consists of |mod0cfa|offs|
\ code to execute for an import def
1 codefields
Do.. dup 4+ w@ \ @IMP
swap @ 4+ execute \ exec 1cfa of MODULE def
..End
2drop
Constant impCfa
\ build an import definition for the name at HERE
: ,import { imp# modCfa -- }
here 1 and IF 0 c, THEN
createHdr -4 allot impCfa , \ create link, cfa
modCfa , imp# 4* 4+ w, latest modCfa 16 + ! ; \ last import link
\ parse the export defs for module
: Import{ { modCfa -- } 0
BEGIN bl word firstChr ascii } <>
WHILE dup modCfa ,import 1+ \ build import defs
REPEAT modCfa 20 + w! ; \ save # of imports
0 value modStart \ beginning addr of module during build
0 value moduleCfa \ cfa of module def during build
0 value cleanMod \ true if clean compile
\ clear object area of bitmap and create the indexed hdr
: clearBits { addr len -- } \ len is of overlay bytes
len bitsLen -> len addr len erase
' bitMap addr ! len 8 - addr 6 + w! 1 addr 4+ w! ;
\ Build a bitmap containing relocation flags for all words in an application.
: bldBits { base len \ hibase inc -- }
base len + -> hibase
base len 2* + 4+ -> bits
bits 4- len clearBits
len 0 DO
2 -> inc
base i+ w@ hiBase i+ w@ <>
IF i dup 1+ len >=
IF 1-
ELSE base i+ 2+ w@ hiBase i+ 2+ w@ <>
IF 4 -> inc ELSE 1- THEN
THEN
2/ bits set: bitmap
THEN
inc +LOOP ;
\ build bitmap for overlay starting at word in stream
: bldOvl { loBase hiBase \ len ^parms -- base totalLen }
hiBase loBase - -> len loBase len bldBits
type# 185 ( module code size: ) len . ." bytes " cr
bits limit: [ bits ] + 4+ -> ^parms
len ^Parms w! hiBase ^parms 2+ ! \ build parms area
hibase ^parms hiBase - 6 ( parmsLen ) + ; ( -- base len )
\ Save binary overlay for an application that was loaded twice
: saveBin { loBase hiBase -- }
loBase hiBase bldovl ( base len )
create: fFcb ?error 138
latest pfa lfa \ find link field of first word in module
BEGIN @ pfa lfa dup @ hiBase < UNTIL
dup @ swap 0 over ! \ ( link addr ) zero out link field
2swap write: fFcb >R ! R> ?error 140
binType saveSig set: fFcb \ set creator, type
close: fFcb drop ;
\ reserve space for export vectors and save modStart
( #exports -- )
: ,Exports here -> modStart 4* 4+ reserve ;
\ initialize the export vectors for module just compiled
: !exports { modCfa \ thisImp -- }
modCfa 16 + @ -> thisImp \ link to nfa of last import
BEGIN thisImp n>count sFind 0= ?error 143
drop dup nfa thisImp =
IF cr thisImp .name msg# 144 0 -> cleanMod
ELSE dup nfa c@ thisImp c! \ copy name flags into import definition
cfa thisImp name>
8+ w@ modStart + ! \ store export cfa
THEN thisImp name> >link @ dup -> thisImp Name> modCfa =
UNTIL ; \ loop until back to module def
\ module builder - loads module source twice, relocates it, saves to disk
\ use: mBuild "modFile"
: Module { \ loMod hiMod mecho docState -- } docs -> docstate -docs
1 -> cleanMod 0 -> moduleCFA
" TASK" sCreate
$ 10000 here - 0 max allot \ 64K compile boundry
new: loadFile setName: topFile
cr type# 176 ( Compiling module: ) getName: topFile type cr
Here -> loMod interpret: topFile \ *** FIRST PASS
loMod @ latest or loMod ! \ mark last def (hi byte is flags)
cleanMod 0= ?error 145
moduleCfa >name n>count binName name: fFcb \ set name of binary file
decho -> mecho -echo \ preserve load echo flag
cr getName: fFcb type type# 177 ( Second pass…) cr
topFile 80 erase setNamePtr: topfile \ fresh fcb (for HFS compatability)
here -> hiMod interpret: topFile \ *** SECOND PASS
hiMod @ latest or hiMod ! \ mark last def (hi byte is flags)
remove: loadfile
mecho -> decho \ restore load echo flag
hiMod loMod - 0= ?error 146
loMod hiMod saveBin
." Binary module " getName: fFcb type ." successfully saved " cr
moduleCFA 12 +
dup @ -dup IF $ 0fffffff and killPtr THEN \ purge old module from memory
dup @ $ 80000000 and swap ! \ and remove pointer from cfa+12
" TASK" sFind 0 -> cleanMod
IF drop dup nfa -> dp lfa @ current ! THEN docState -> docs ;
\ begin a module source definition
: :Module
@pfa cfa dup @ modCode <> ?error 147
dup -> moduleCfa cleanMod
0= ?error 164 cr \ Use "Module" loader for modules
moduleCFA ?mlock ?error 188 \ module is locked
20 + w@ dup . type# 178 ( export entries ) cr
,Exports ; \ build export vectors
\ Cause the module to remain locked after execution terminates
: Locked 1 modStart c! ;
\ end a module source definition
: ;Module
moduleCfa dup 0= ?error 148
!exports ;
\ if any of the imported words are defined in the module as immediate,
\ you should move all of them to the last of the import list and
\ then add n immediates to mark them as such.
: immediates { num \ addr -- } latest -> addr
num 0 DO addr 64 toggle addr 1 traverse 1+ @ -> addr LOOP ;